
Intro
This is a listing of things I like and dislike about Python:
packages & dependencies
pydantic - A library for data validation and serialization FastAPI - Powered by Pydantic and offers an easy-to-use framework for building APIs
syntax
Likes: - Context Managers (e.g. with some_resource() as r: ) - A language construct for setup and shutdown, very handy for abstractions that have a lot of setup and need to tidy up after use - comprehensions
Idioms & Patterns
An idiomatic way to represent in-memory caching objects in Python is to use the class obj pattern. Since all classes are imported once per run-time by the import system in Python, you can design your caching logic like so:
class Cache():
_cache = None
def __init__(self, ):
print("cache_constructed")
@classmethod
def populate_cache(cls, *args, **kwargs):
"""doc-string"""
if not cls._cache:
print("")
cls._cache = [i for i in range(0, 20, 2)]
else:
print("already populated")
@classmethod
def get_nums(cls, ) -> Generator:
"""
returns nums cache
"""
yield from cls._cachethen when you import this class in one module, all subsequent imports are all reference the same cache object:
#module_a
from cache import Cache
Cache.populate_cache()
print(list(Cache.get_nums()))
class A():
def __init__(self) -> None:
pass#module_b
from cache import Cache
Cache.populate_cache()
class B():
def __init__(self) -> None:
passthen when you import both modules in module_c, Cache was already imported in module_a:
#module_c
from module_a import A
from module_b import B
print("module C")when you run module_c, you get this output:
path/to/dir$ uv run module_c.py
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
already populated
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
module CReferences